//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.kun.portal.webframe.service;

import com.kun.framework.core.util.SimpleKey;
import com.kun.framework.web.web.vo.ValueLabelVo;
import com.kun.portal.webframe.dao.FwModuleDao;
import com.kun.portal.webframe.dao.FwRoleDao;
import com.kun.portal.webframe.dao.FwRoleModuleDao;
import com.kun.portal.webframe.po.FwModulePo;
import com.kun.portal.webframe.po.FwRoleModulePo;
import com.kun.portal.webframe.po.FwRolePo;
import com.kun.portal.webframe.po.FwUserPo;
import com.kun.portal.webframe.vo.Teams;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class FwModuleService {
    public static final String DEFAULT_ROOT_MODULE_CODE = "02";
    public static final String MENU_SPLIT = "-";
    @Autowired
    private FwModuleDao fwmoduleDao;
    @Autowired
    private EntityManager entityManager;
    @Autowired
    private FwRoleModuleDao fwRoleModuleDao;
    @Autowired
    private FwRoleDao fwRoleDao;

    public FwModuleService() {
    }

    public Page<FwModulePo> queryAll(Pageable pageable) {
        return this.fwmoduleDao.findAll(pageable);
    }

    public Page<FwModulePo> findByCreatorAndModuleUrlAndModuleNameContaining(String userId, String moduleUrl, String moduleName, Pageable pageable) {
        return this.fwmoduleDao.findByCreatorAndModuleUrlAndModuleNameContaining(userId, moduleUrl, moduleName, pageable);
    }

    public Page<FwModulePo> findByCreatorAndModuleTypeAndModuleNameContaining(String userId, String moduleType, String moduleName, Pageable pageable) {
        return this.fwmoduleDao.findByCreatorAndModuleTypeAndModuleNameContainingOrderByModuleCode(userId, moduleType, moduleName, pageable);
    }

    public FwModulePo addFwModule(FwModulePo fwmodule) {
        FwModulePo fwmodulePo = (FwModulePo)this.fwmoduleDao.save(this.createModuleCode(fwmodule));
        return fwmodulePo;
    }

    private FwModulePo createModuleCode(FwModulePo fwmodule) {
        String moduleCode = StringUtils.isNoneBlank(new CharSequence[]{fwmodule.getModuleCode()})?fwmodule.getModuleCode():SimpleKey.genShortUuid();
        if(StringUtils.isNoneBlank(new CharSequence[]{fwmodule.getParentCode()})) {
            fwmodule.setModuleCode(fwmodule.getParentCode() + "-" + moduleCode);
        } else {
            fwmodule.setModuleCode(moduleCode);
        }

        return fwmodule;
    }

    public FwModulePo updateFwModule(FwModulePo fwmodule) {
        FwModulePo fwmodulePo = (FwModulePo)this.fwmoduleDao.save(fwmodule);
        return fwmodulePo;
    }

    @Transactional
    public void deleteFwModule(String moduleId) {
        List<FwModulePo> fwModulePos = this.fwmoduleDao.findChildrenByModuleId(moduleId);
        this.fwmoduleDao.delete(fwModulePos);
        this.fwmoduleDao.delete(moduleId);
    }

    public List<ValueLabelVo> findFwModuleByCreator(String creatorId) {
        Query query = this.entityManager.createNativeQuery("select r.module_id as value, r.module_code as code, r.module_name as label from fw_module r where module_status!='0' and r.creator=?1", ValueLabelVo.class);
        query.setParameter(1, creatorId);
        return query.getResultList();
    }

    public List<String> findFwModuleByRoleId(String roleId) {
        Query query = this.entityManager.createNativeQuery("select r.module_id from fw_role_module r where r.role_id=?1");
        query.setParameter(1, roleId);
        return query.getResultList();
    }

    public List<String> findFwModuleByTeamId(String teamId) {
        Query query = this.entityManager.createNativeQuery("select r.module_id from fw_team_module r where r.team_id=?1");
        query.setParameter(1, teamId);
        return query.getResultList();
    }

    public String findMaxModuleCodeByParentCode(String parentCode) {
        Query query;
        if(parentCode == null) {
            query = this.entityManager.createNativeQuery("select max(module_code) from fw_module where parent_code is null");
            return (String)query.getSingleResult();
        } else {
            query = this.entityManager.createNativeQuery("select max(module_code) from fw_module where parent_code = ?1");
            query.setParameter(1, parentCode);
            return (String)query.getSingleResult();
        }
    }

    public void updateFwRoleModuleByRoleId(List<String> moduleIds, String roleId) {
        this.fwRoleModuleDao.deleteByRoleId(roleId);
        List<FwRoleModulePo> pos = new ArrayList();

        for(int i = 0; i < moduleIds.size(); ++i) {
            FwRoleModulePo po = new FwRoleModulePo();
            po.setModuleId((String)moduleIds.get(i));
            po.setRoleId(roleId);
            pos.add(po);
        }

        this.fwRoleModuleDao.save(pos);
    }

    public void updateFwRoleModuleByModuleId(List<String> roleIds, String moduleId) {
        this.fwRoleModuleDao.deleteByModuleId(moduleId);
        List<FwRoleModulePo> pos = new ArrayList();
        Iterator var5 = roleIds.iterator();

        while(var5.hasNext()) {
            String roleId = (String)var5.next();
            FwRoleModulePo po = new FwRoleModulePo();
            po.setModuleId(moduleId);
            po.setRoleId(roleId);
            pos.add(po);
        }

        this.fwRoleModuleDao.save(pos);
    }

    public List<FwModulePo> findByCreatorAndModuleTypeAndParentCodeIsNullOrderByModuleId(String userId, String type) {
        return this.fwmoduleDao.findByCreatorAndModuleTypeAndParentCodeIsNullOrderByModuleId(userId, type);
    }

    public List<FwModulePo> findByCreatorAndModuleTypeAndParentCodeEqualsOrderByModuleId(String userId, String type, String key) {
        return this.fwmoduleDao.findByCreatorAndModuleTypeAndParentCodeEqualsOrderByModuleId(userId, type, key);
    }

    public List<FwModulePo> fwmodulePermissionTree(String userId) {
        Query query = this.entityManager.createNativeQuery("select distinct fm.* from fw_module fm right join (select m.module_code from fw_module m  right join fw_role_module rm on rm.module_id = m.module_id right join fw_role_user ru on rm.role_id = ru.role_id where ru.user_id = ?1) tmp on tmp.module_code like CONCAT(fm.module_code,'%') and tmp.module_code not like CONCAT('02','%') order by fm.module_seq", FwModulePo.class);
        query.setParameter(1, userId);
        return query.getResultList();
    }


    public List<FwModulePo> fwmodulePermissionTree(FwUserPo user) {
        String userId = user.getUserId();
        Query query = this.entityManager.createQuery("select distinct m from FwTeamPo t right join t.userList u " +
                "left join u.roles r1 left join t.roleSet r2 left join FwRoleModulePo mr on(mr.roleId = r1.roleId or mr.roleId = r2.roleId)  left join FwModulePo m  on mr.moduleId = m.id where u.userId = :userId");
        query.setParameter("userId",userId);
        return query.getResultList();
    }
    public List<FwModulePo> fwmodulePermissionTree(String parentCode, String teamId, String userId) {
        return (List)this.fwmoduleDao.findPermissionModule(parentCode + "%", teamId, userId).stream().distinct().collect(Collectors.toList());
    }

    public List<FwModulePo> findByParentCodeEqualsOrderByModuleSeq(String parentCode, String teamId, String userId) {
        Query query = this.entityManager.createNativeQuery("select distinct m.* from  fw_module m  right join fw_role_module rm on rm.module_id = m.module_id  right join fw_role r on r.role_id = rm.role_id and (r.team_id=?3 or r.team_id is null or r.team_id = '')  right join fw_role_user ru on rm.role_id = ru.role_id  where m.module_status!='0' and m.parent_code = ?1 and ru.user_id = ?2 order by m.module_seq", FwModulePo.class);
        query.setParameter(1, parentCode);
        query.setParameter(2, userId);
        query.setParameter(3, teamId);
        return query.getResultList();
    }

    public Page<FwModulePo> findByModuleUrlAndModuleNameContaining(String userId, String moduleUrl, String key, Pageable pageable) {
        return this.fwmoduleDao.findByModuleUrlAndModuleNameContaining(moduleUrl, key, pageable);
    }

    public List<Map<String, Object>> findParentModuleByTeamId(String parentId) {
        List menus;
        Query query;
        if(StringUtils.isEmpty(parentId)) {
            query = this.entityManager.createNativeQuery("SELECT module_id id,module_code code,module_name label,parent_code pcode FROM fw_module where module_status!='0' ORDER BY module_seq");
            ((SQLQuery)query.unwrap(SQLQuery.class)).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
            menus = query.getResultList();
        } else {
            query = this.entityManager.createNativeQuery("SELECT module_id id,module_code code,module_name label,parent_code pcode FROM fw_module a WHERE module_status!='0' AND EXISTS(SELECT * FROM fw_team_module b where a.module_id=b.module_id and b.team_id=?) ORDER BY module_seq");
            ((SQLQuery)query.unwrap(SQLQuery.class)).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
            query.setParameter(1, parentId);
            menus = query.getResultList();
        }

        return this.listToTree(menus, "code", "pcode", "children");
    }

    public List<Map<String, Object>> findParentModuleByUser(String teamid, String userid) {
        String sql = "SELECT module_id id,module_code code,module_name label,parent_code pcode FROM fw_module a WHERE module_status!='0' ";
//                + (Teams.SysTeam.name().equals(teamid)?"":
//                "  AND module_id in (SELECT b.module_id FROM fw_role c, fw_role_module b                      WHERE c.role_status!='0' AND c.role_id = b.role_id                       AND (team_id = ?1 OR team_id IS NULL OR team_id = '')                       AND c.role_id IN (SELECT role_id FROM fw_role_user WHERE user_id=?2)) ") + "ORDER BY module_seq";




        Query query = this.entityManager.createNativeQuery(sql);
        ((SQLQuery)query.unwrap(SQLQuery.class)).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
//        if(!Teams.SysTeam.name().equals(teamid)) {
//            query.setParameter(1, teamid);
//            query.setParameter(2, userid);
//        }

        List<Map<String, Object>> menus = query.getResultList();
        return this.listToTree(menus, "code", "pcode", "children");
    }

    public List<Map<String, Object>> findParentModuleByRoleId(String roleId) {
        return this.findParentModuleByTeamId(((FwRolePo)this.fwRoleDao.findOne(roleId)).getTeamId());
    }

    public List<Map<String, Object>> listToTree(List<Map<String, Object>> list, String idName, String pidName, String childName) {
        List<Map<String, Object>> resultList = new ArrayList();
        Iterator var7 = list.iterator();

        while(true) {
            Map item;
            do {
                if(!var7.hasNext()) {
                    return resultList;
                }

                item = (Map)var7.next();
            } while(item.get(pidName) != null && !"02".equals(item.get(pidName)));

            this.getChildList(list, item, idName, pidName, childName);
            resultList.add(item);
        }
    }

    public Map<String, Object> getChildList(List<Map<String, Object>> list, Map<String, Object> map, String idName, String pidName, String childName) {
        map.put(childName, new ArrayList());
        Iterator var7 = list.iterator();

        while(var7.hasNext()) {
            Map<String, Object> item = (Map)var7.next();
            if(item.get(pidName) != null && item.get(pidName).equals(map.get(idName))) {
                this.getChildList(list, item, idName, pidName, childName);
                ((List)map.get(childName)).add(item);
            }
        }

        return map;
    }
}
